package com.lp.controller.iot;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.lp.bo.IotHistorySensorDataBO;
import com.lp.bo.IotSensorInfoBO;
import com.lp.cache.CacheName;
import com.lp.cache.ProCacheUtil;
import com.lp.cfg.ProConfig;
import com.lp.common.Code;
import com.lp.common.Constants;
import com.lp.common.RequestURLIOT;
import com.lp.controller.BaseController;
import com.lp.service.IotHistorySensorDataService;
import com.lp.util.DateUtils;
import com.lp.util.ObjectUtil;
import com.lp.util.ResultMapUtils;


@Controller
public class IotHistorySensorInfoController extends BaseController {

	/**
	 * 检索
	 * @param response
	 * @param 
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST, value = RequestURLIOT.SensorHistoryInfo.SENSOR_HISTORY_INFO_PAGE)
	public ModelAndView selectPage(HttpServletResponse response, 
			@RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey ,
			@RequestBody IotHistorySensorDataBO obj,
			@RequestParam(required=false) Integer pageSize ,
			@RequestParam Integer paged ) {
		Map<String, Object> resultMap = getResultMap();
		try {
			// 这边暂时不管，当前场景是否是该有用户的数据
			if( ObjectUtil.isNotEmpty(obj.getSensor_id()) || ObjectUtil.isNotEmpty(obj.getScene_id()) ){
				if(  ObjectUtil.isNotEmpty( obj.getQuery_interval_type())){
					if(obj.getQuery_interval_type() == 1){
						obj.setInterval_p1("%Y%d%m%k%i");
						obj.setInterval_p2("%s");
						obj.setInterval_p3(30);
					}else if(obj.getQuery_interval_type() == 2){
						obj.setInterval_p1("%Y%d%m%k");
						obj.setInterval_p2("%i");
						obj.setInterval_p3(1);
					}else if(obj.getQuery_interval_type() == 3){
						obj.setInterval_p1("%Y%d%m%k");
						obj.setInterval_p2("%i");
						obj.setInterval_p3(30);
					}else if(obj.getQuery_interval_type() == 4){
						obj.setInterval_p1("%Y%d%m");
						obj.setInterval_p2("%k");
						obj.setInterval_p3(1);
					}
					resultMap = service.selectPageList("IotHistorySensorData.selectGroupByPage",getPageBean(paged,pageSize), obj);
				}else{
					resultMap = service.selectPageList("IotHistorySensorData.selectPage",getPageBean(paged,pageSize), obj);						
				}
			}
		} catch (Exception e) {
			exception(e,resultMap, obj);
		}
		return getModelAndView(response, resultMap);
	}
	
	
	/**
	 * 检索列表
	 * @param response
	 * @param 
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST, value = RequestURLIOT.SensorHistoryInfo.SENSOR_HISTORY_INFO_LIST)
	public ModelAndView selectList(HttpServletResponse response, 
			@RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey ,
			@RequestBody IotHistorySensorDataBO obj) {
		Map<String, Object> resultMap = getResultMap();
		try {
			if(ObjectUtil.isNotEmpty(obj.getStart_time()) && ObjectUtil.isNotEmpty(obj.getEnd_time()) ){
				
				// 这边做特殊情况，传 node_id, sensor_device_id 和 port_id的时候，转成传感器id去检索历史数据
				if(ObjectUtil.isEmpty(obj.getSensor_id()) &&  ObjectUtil.isNotEmpty(obj.getNode_id()) && 
						ObjectUtil.isNotEmpty(obj.getSensor_device_id()) && ObjectUtil.isNotEmpty(obj.getPort_id()) ){
					IotSensorInfoBO sensorInfo = ProCacheUtil.getCache(CacheName.SENSORINFO_NSP, obj.getNode_id()+"-"+obj.getSensor_device_id()+"-"+obj.getPort_id()) ;
					obj.setSensor_id(sensorInfo.getId());
				}
				// 这边判断时间不允许超过一个月，否则强行设置一个月；
				Date start_time = DateUtils.parse(DateUtils.simpleALL, obj.getStart_time());
				Date end_time = DateUtils.parse(DateUtils.simpleALL,obj.getEnd_time());
				if( start_time.getTime() + (long)32*24*3600*1000 < end_time.getTime()){
					// 时间出错
					obj.setStart_time( DateUtils.format(DateUtils.simpleALL, DateUtils.getBeforeOneDateTime(end_time))  );
				}
				// 这边暂时不管，当前场景是否是该有用户的数据
				if( ObjectUtil.isNotEmpty(obj.getSensor_id()) || ObjectUtil.isNotEmpty(obj.getScene_id()) ){
					if(  ObjectUtil.isNotEmpty( obj.getQuery_interval_type())){
						if(obj.getQuery_interval_type() == 1){
							obj.setInterval_p1("%Y%d%m%k%i");
							obj.setInterval_p2("%s");
							obj.setInterval_p3(30);
						}else if(obj.getQuery_interval_type() == 2){
							obj.setInterval_p1("%Y%d%m%k");
							obj.setInterval_p2("%i");
							obj.setInterval_p3(1);
						}else if(obj.getQuery_interval_type() == 3){
							obj.setInterval_p1("%Y%d%m%k");
							obj.setInterval_p2("%i");
							obj.setInterval_p3(30);
						}else if(obj.getQuery_interval_type() == 4){
							obj.setInterval_p1("%Y%d%m");
							obj.setInterval_p2("%k");
							obj.setInterval_p3(1);
						}
						resultMap = service.selectList("IotHistorySensorData.selectGroupByPage", obj);
					}else{
						resultMap = service.selectList("IotHistorySensorData.selectPage", obj) ;			
					}
				}
			}else{
				putStatusCode(resultMap, Code.ResponseCode.SystemCode.PARAM_ERROR);
			}
		} catch (Exception e) {
			exception(e,resultMap, obj);
		}
		return getModelAndView(response, resultMap);
	}
	
	@Autowired
	private IotHistorySensorDataService hisSensorService ;
	
	/**
	 * 批量获取多个传感器历史数据
	 * @param response
	 * @param userKey
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST, value = RequestURLIOT.SensorHistoryInfo.SENSORS_HISTORY_DATA)
	public ModelAndView selectDatas(HttpServletResponse response, 
			@RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey , @RequestBody IotHistorySensorDataBO obj,
			@RequestParam(required=false) Integer pageSize ,
			@RequestParam Integer paged ) {
		Map<String, Object> resultMap = getResultMap();
		try {
			if(pageSize == null)
				pageSize = 300 ;
			obj.setLimit(pageSize);
			obj.setOffset( (paged-1)*pageSize );
			resultMap = hisSensorService.getHistorySensorData(obj) ;
			resultMap.put("paged", paged) ;
		} catch (Exception e) {
			exception(e,resultMap, obj);
		}
		return getModelAndView(response, resultMap);
	}
	
	/**
	 * Excel 下载
	 * @param response
	 * @param obj
	 * @return
	 */
	@RequestMapping(method = RequestMethod.GET, value = RequestURLIOT.SensorHistoryInfo.SENSOR_HISTORY_INFO_INFO )
	public void excel(HttpServletResponse response, 
			IotHistorySensorDataBO obj ) {
		Map<String, Object> resultMap = getResultMap();
		try {
			// 这边需要对查询的数据进行判断是否数据量过大，如果大于5000 条，则通过CSV下载，并且CSV通过分段下载
			int allCount = service.count("IotHistorySensorData.selectPageCount", obj) ;
			if(allCount < 1){
				downExcel("IotHistorySensorData.select","历史数据下载","tpl/xls/history_sensor_data_template",obj, response);				
			}else{
				// 这边就需要分段下载
				int num = allCount / 5000 +1 ;
				
				 String fileRealPath = ProConfig.LOCAL_FILE_PATH + Constants.FileRealPath.NORMAL +"/"
						 	+ DateUtils.format(DateUtils.dtShort , new Date()) + "/"
						 	 ;
				
				 if(! new File(fileRealPath).exists()){
					 new File(fileRealPath).mkdirs();
				 }
				 File f = new File(fileRealPath 
							+ "historySensorData" + DateUtils.format(DateUtils.dtShort , new Date())+".csv");
				FileOutputStream fos = new FileOutputStream(f );
				
				// excel兼容
				fos.write(new byte[] { (byte) 0xEF, (byte) 0xBB,(byte) 0xBF } );
				
				OutputStreamWriter osw = new OutputStreamWriter(fos, "utf-8");
				
				// csv 格式
				CSVFormat csvFormat = CSVFormat.DEFAULT.withHeader("序号", "传感器名称", "数值", "时间");  //  "类型"
				CSVPrinter csvPrinter = new CSVPrinter(osw, csvFormat);
				for (int i = 0; i < num; i++) {
					obj.setLimit(5000);
					obj.setOffset(i*5000);
					List<IotHistorySensorDataBO> list = getData( service.selectList("IotHistorySensorData.selectPage", obj) );
					for(int j=0;j<list.size();j++){
						csvPrinter.printRecord(i*5000 + (j+1) ,list.get(j).getSensor_name(), list.get(j).getSdata()+list.get(j).getData().get("measure_unit_type"),
								list.get(j).getAtimestr() );  //   list.get(j).getData().get("iot_sensor_type")
					}
					// 这边需要对list 清空缓存
					list = null ;
					System.gc();
				}
				csvPrinter.flush();
				csvPrinter.close();
				
				// 返回文件流
				InputStream bis = new BufferedInputStream(new FileInputStream(f));
				byte[] buffer = new byte[bis.available()];
				bis.read(buffer);
				bis.close();
				// 清空response
				response.reset();
				// 设置response的Header
				response.addHeader("Content-Disposition",
						"attachment;filename=" + new String(f.getName().getBytes("gb2312"), "ISO8859-1"));
				response.addHeader("Content-Length", "" + f.length());
				OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
				response.setContentType("application/vnd.ms-excel;charset=gb2312");
    
				toClient.write(buffer);
				toClient.flush();
				toClient.close();
				// 删除生成的临时文件
				if (f.exists()) {
					f.delete();
				}
			}
		} catch (Exception e) {
			exception(e,resultMap, obj);
		}
	}
	
	/**
	 * 插入
	 * @param response
	 * @param 
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST, value = RequestURLIOT.SensorHistoryInfo.SENSOR_HISTORY_INFO )
	public ModelAndView save(HttpServletResponse response, 
			@RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey ,
			@RequestBody IotHistorySensorDataBO obj ) {
		Map<String, Object> resultMap = getResultMap();
		try {
			
			resultMap = service.insert("IotHistorySensorData.insert", obj) ;
		} catch (Exception e) {
			exception(e,resultMap, obj);
		}
		return getModelAndView(response, resultMap);
	}
	
	/**
	 * 查询单个
	 * @param response
	 * @param id
	 * @return
	 */
	@RequestMapping(method = RequestMethod.GET, value = RequestURLIOT.SensorHistoryInfo.SENSOR_HISTORY_INFO)
	public ModelAndView selectOne(HttpServletResponse response, 
			@RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey ,
			@RequestParam Integer id ) {
		Map<String, Object> resultMap = getResultMap();
		try {
			
			resultMap = service.selectOne("IotHistorySensorData.selectOne", new IotHistorySensorDataBO(id)) ;
		} catch (Exception e) {
			exception(e,resultMap, id);
		}
		return getModelAndView(response, resultMap);
	}
	
	/**
	 * 更新
	 * @param response
	 * @param obj
	 * @return
	 */
	@RequestMapping(method = RequestMethod.PUT, value = RequestURLIOT.SensorHistoryInfo.SENSOR_HISTORY_INFO)
	public ModelAndView update(HttpServletResponse response, 
			@RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey ,
			@RequestBody IotHistorySensorDataBO obj ) {
		Map<String, Object> resultMap = getResultMap();
		try {
			resultMap = service.update("IotHistorySensorData.update", obj) ;
		} catch (Exception e) {
			exception(e,resultMap, obj);
		}
		return getModelAndView(response, resultMap);
	}
	
	/**
	 * 删除
	 * @param response
	 * @param id
	 * @return
	 */
	@RequestMapping(method = RequestMethod.DELETE, value = RequestURLIOT.SensorHistoryInfo.SENSOR_HISTORY_INFO)
	public ModelAndView delete(HttpServletResponse response, 
			@RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey ,
			@RequestParam Integer id ) {
		Map<String, Object> resultMap = getResultMap();
		try {
			IotHistorySensorDataBO obj = new IotHistorySensorDataBO();
			if(ObjectUtil.isEmpty(id)){
				putStatusCode(resultMap, Code.ResponseCode.SystemCode.PARAM_ERROR);
			}else{
				obj.setId(id);
				obj.setDelete_flag(Constants.DELETE.YES);
				resultMap = service.update("IotHistorySensorData.update", obj) ;		
			}
		} catch (Exception e) {
			exception(e,resultMap, id);
		}
		return getModelAndView(response, resultMap);
	}
}
